package com.price.sample.http

import android.app.Activity
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.price.common.extend.launch
import com.price.httplib.error.ExceptionUtil
import com.price.sample.http.beans.WanBaseResponse
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch


inline fun <T : Any> Activity.launchHttp(
    owner: LifecycleOwner,
    dispatcher: CoroutineDispatcher = Dispatchers.IO,
    crossinline action: suspend () -> WanBaseResponse<T>,
    crossinline success: (T?) -> Unit,
    crossinline fail: (code: Int?, msg: String?) -> Unit? = { _, _ -> },
    crossinline end: () -> Unit? = {}
) {
    owner.lifecycleScope.launch(dispatcher) {
        try {
            val result = action()
            owner.lifecycleScope.launch(Dispatchers.Main) {
                when (result.errorCode) {
                    0 -> success(result.data)
                    else -> fail(result.errorCode, result.errorMsg)
                }
                end()
            }
        } catch (e: Exception) {
            val customError = ExceptionUtil.catchException(e)
            owner.lifecycleScope.launch(Dispatchers.Main) {
                fail(customError.code, customError.errMsg)
                end()
            }
        }
    }
}

inline fun <T : Any> Fragment.launchHttp(
    owner: LifecycleOwner,
    dispatcher: CoroutineDispatcher = Dispatchers.IO,
    crossinline action: suspend () -> WanBaseResponse<T>,
    crossinline success: (T?) -> Unit,
    crossinline fail: (code: Int?, msg: String?) -> Unit? = { _, _ -> },
    crossinline end: () -> Unit? = {}
) {
    owner.lifecycleScope.launch(dispatcher) {
        try {
            val result = action()
            owner.lifecycleScope.launch(Dispatchers.Main) {
                when (result.errorCode) {
                    0 -> success(result.data)
                    else -> fail(result.errorCode, result.errorMsg)
                }
                end()
            }
        } catch (e: Exception) {
            val customError = ExceptionUtil.catchException(e)
            owner.lifecycleScope.launch(Dispatchers.Main) {
                fail(customError.code, customError.errMsg)
                end()
            }
        }
    }
}

inline fun <T : Any> Context.launchHttp(
    dispatcher: CoroutineDispatcher = Dispatchers.IO,
    crossinline action: suspend () -> WanBaseResponse<T>,
    crossinline success: (T?) -> Unit,
    crossinline fail: (code: Int?, msg: String?) -> Unit? = { _, _ -> },
    crossinline end: () -> Unit? = {}
) {
    launch(dispatcher) {
        try {
            val result = action()
            launch(Dispatchers.Main) {
                when (result.errorCode) {
                    0 -> success(result.data)
                    else -> fail(result.errorCode, result.errorMsg)
                }
            }
        } catch (e: Exception) {
            val customError = ExceptionUtil.catchException(e)
            launch(Dispatchers.Main) {
                fail(customError.code, customError.errMsg)
                end()
            }
        }
    }
}